/**
 * @file simulation.h
 * @brief Function definitions to do simulations an a given circuit.
 *
 * This file contains all the function definitions suggested in the assignment file.
 * Type definitions are included as well, but were given by the assignment.
 */
#ifndef SIMULATION_H_
#define SIMULATION_H_

#include "logicports.h"
#include "netlist.h"


extern char *optarg;
extern int optind, opterr;


typedef enum{None, User,Exhaustive,Testbench}combinational_type;

typedef struct event {
double time_stamp;
circuit_item *item;
int update_value;
struct event *next_event;
} event;


/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_or_gate (int inputs[], int size);

/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_nor_gate (int inputs [], int size);

/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_and_gate(int inputs [], int size);

/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_nand_gate (int inputs [], int size);

/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_xor_gate (int inputs [], int size);

/**
 *
 * @param inputs
 * @param size
 * @return
 */
int vector_xnor_gate (int inputs [], int size);

/**
 *
 * @param table
 * @param table_size
 * @return
 */
double print_timing_information(node *table[], int table_size);

/**
 *
 * @param event_list
 * @param time_stamp
 * @param item
 * @param update_value
 */
void schedule_event(event **event_list, double time_stamp, circuit_item *item, int update_value);

/**
 *
 * @param inputs
 * @param bitmask
 * @param time_stamp
 * @param interface
 * @param event_list
 */
void add_input_events(int inputs[], int bitmask[], double time_stamp, s_interface *interface,event **event_list);

/**
 *
 * @param event_list
 */
void sim_single_event(event **event_list);

/**
 *
 * @param event_list
 */
void sim_all_events(event **event_list);

/**
 *
 * @param interface
 * @return
 */
double user_sim(s_interface *interface);

/**
 *
 * @param interface
 * @return
 */
double exhaustive_sim(s_interface *interface);

/**
 *
 * @param fp_tb
 * @param interface
 * @param event_list
 */
void init_TB_based_events(FILE *fp_tb,s_interface *interface,event **event_list);

/**
 *
 * @param fp_tb
 * @param s_interface
 * @param event_list
 * @param fp_out
 * @return
 */
double testbench_sim(FILE *fp_tb, s_interface *interface, FILE *fp_out);

/**
 *
 * @param a
 * @param b
 * @param size
 * @return
 */
int compare_arrays(int *a,int *b, int size);

/**
 *
 */
void print_usage();

#endif /* SIMULATION_H_ */
